# -*- coding: utf-8 -*-
# @author: liuhuaijin
# @email: liuhuaijin@shanshu.ai
# @date: 2025/8/8 14:52
import os
import json
# import uuid
from wcwidth import wcwidth
from datetime import datetime
from traceback import format_exc
from flask import Flask, render_template, request, jsonify, send_file

from utils.log_util import logger

app = Flask(__name__)

# 数据存储文件
DATA_FILE = 'flight_data.json'
TEMPLATE_FILE = 'templates.json'


def safe_wcwidth(char):
    """安全获取字符的显示宽度，控制字符等返回0"""
    w = wcwidth(char)
    return max(0, w) if w >= 0 else 0


def wrap_string_by_chinese_width(s, width_in_chinese=28):
    target_width = width_in_chinese * 2  # 每个汉字占2列
    result = []
    current_width = 0
    start_index = 0
    i = 0
    while i < len(s):
        char = s[i]
        w = safe_wcwidth(char)
        if w == 0:
            # 不占宽度的字符（如控制字符），直接计入当前段
            i += 1
            continue
        if current_width + w > target_width:
            # 当前字符放不下，先保存前面的段
            result.append(s[start_index:i].replace(" ", "  "))
            # 重置起点和宽度
            start_index = i
            current_width = 0
            # 注意：不增加 i，下一轮继续处理当前字符
        else:
            current_width += w
            i += 1
    # 添加最后一段
    if start_index < len(s):
        result.append(s[start_index:].replace(" ", "  "))
    return result


def load_data():
    """加载数据"""
    try:
        with open(DATA_FILE, 'r', encoding='utf-8') as f:
            return json.load(f)
    except:
        return {
            "current_data": {
                "date": "",
                "week": "",
                "route_name": "",
                "flight_number": "",
                "plane_number": "",
                "captain_config": "",
                "segments": [
                    {
                        "segment_number": "1",
                        "departure_time": "",
                        "arrival_time": "",
                        "duration": "",
                        "distance": "",
                        "altitude": "",
                        "airport": "",
                        "first_class_meals": "",
                        "economy_meals": "",
                        "crew_meals": "",
                        "upgrade_prices": [
                            {"class": "C", "price": "500"},
                            {"class": "Y", "price": "300"}
                        ],
                        "first_class_layout": False,
                        "first_class_count": "",
                        "economy_count": "",
                        "special_passengers": ""
                    }
                ]
            },
            "basic_data": {
                "airports": ["北京首都", "上海虹桥", "广州白云", "深圳宝安"],
                "meals": ["鸡肉饭", "牛肉面", "素食", "海鲜餐"],
                "upgrade_templates": {
                    "标准模板": [
                        {"class": "C", "price": "500"},
                        {"class": "Y", "price": "300"}
                    ],
                    "高端模板": [
                        {"class": "C", "price": "800"},
                        {"class": "Y", "price": "500"}
                    ]
                }
            }
        }


def save_data(data):
    """保存数据"""
    with open(DATA_FILE, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)


def generate_html(data):
    """生成HTML文件"""
    html_content = """<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>航班信息</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: Arial, sans-serif;
            background: white;
            color: black;
            width: 100vh;
            overflow-x: auto;
            overflow-y: auto;
            font-size: 18px;
            line-height: 1.2;
            transform: rotate(90deg);
            transform-origin: left center;
            position: absolute;
            top: -10%;
            left: 50%;
        }

        /* 主容器 - 水平排列区块 */
        .blocks-container {
            display: flex;
            gap: 20px;
            width: max-content;
        }

        /* 每个区块 - 13行 × 28个汉字 */
        .content-block {
            width: 500px; /* 28字 × 28px */
            display: flex;
            flex-direction: column;
            gap: 2px;
        }

        /* 内容行 */
        .content-line {
            padding: 3px 5px;
            min-height: 25px;
            white-space: pre; /* 保留空格 */
            overflow: hidden;
            text-overflow: ellipsis;
        }

        /* 左对齐行 */
        .left-align {
            text-align: left;
            white-space: pre;
        }

        /* 特殊乘客区块 - 允许多行 */
        .special-passengers {
            padding: 3px 5px;
            min-height: 25px;
            white-space: pre;
            word-wrap: break-word;
        }

        /* 航段符号 */
        .segment-symbol {
            font-weight: bold;
            font-size: 18px;
            margin-right: 10px;
        }

        /* 表格样式 */
        .upgrade-table {
            border-collapse: collapse;
            width: 500px;
            font-size: 18px;
            margin: 0;
        }

        .upgrade-table, .upgrade-table th, .upgrade-table td {
            border: 1px solid #000;
        }

        .upgrade-table th, .upgrade-table td {
            padding: 2px 8px;
            text-align: center;
        }

        /* 头等舱布局 - 使用空格均匀分布 */
        .first-class-row {
            white-space: pre;
            font-size: 18px;
            padding: 1px 0;
        }

        /* 分隔线 */
        .divider {
            border-bottom: 1px dashed #ccc;
            margin: 2px 0;
        }
    </style>
</head>
<body>
    <div class="blocks-container" id="blocksContainer">"""

    # 准备所有要显示的内容行
    all_content_lines = []

    # 获取航段数据
    segments = data.get('segments', [])

    # 第1行：航班日期、星期、航班号、飞机号、机场（用空格分隔）
    line1_parts = [
        data.get('date', ''),
        data.get('week', ''),
        data.get('route_name', ''),
        data.get('flight_number', ''),
        data.get('plane_number', ''),
        # segments[0].get('airport', '') if segments else ''
    ]
    # 过滤空值并用空格连接
    line1_content = '    '.join([part for part in line1_parts if part])
    all_content_lines.append(f'<div class="content-line left-align">{line1_content}</div>')

    # 第2行：机组配置（左对齐）
    captain_config = data.get('captain_config', '')
    if captain_config:
        all_content_lines.append(f'<div class="content-line left-align">{captain_config}</div>')

    # 添加航段信息
    segment_symbols = ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩']

    if not segments:
        all_content_lines.append('<div class="content-line left-align">警告：没有航段数据</div>')
    else:
        for i, segment in enumerate(segments):
            symbol = segment_symbols[i] if i < len(segment_symbols) else str(i + 1)

            # 获取头等舱布局状态
            first_class_layout = segment.get('first_class_layout', False)
            if isinstance(first_class_layout, str):
                first_class_layout = first_class_layout.lower() == 'true'

            # 第3行：航段信息（左对齐，用空格分隔）
            departure_time = segment.get('departure_time', '')
            arrival_time = segment.get('arrival_time', '')
            duration = segment.get('duration', '      ')
            distance = segment.get('distance', '')
            altitude = segment.get('altitude', '')
            airport = segment.get('airport', '')
            if not distance.endswith('km'):
                distance += 'km'
            if not altitude.endswith('km'):
                altitude += 'm'
            segment_info_parts = [
                departure_time + ' ~ ' + arrival_time, duration, distance, altitude, airport
            ]
            segment_info_content = f'{symbol}  ' + '    '.join([part for part in segment_info_parts])
            all_content_lines.append(f'<div class="content-line left-align">{segment_info_content}</div>')

            # 第4行：餐食信息（标注C、Y、机组）
            meals_content = ""
            first_class_meals = segment.get('first_class_meals', '')
            economy_meals = segment.get('economy_meals', '')
            crew_meals = segment.get('crew_meals', '')

            if first_class_meals or economy_meals or crew_meals:
                meals_parts = []
                if first_class_meals:
                    meals_parts.append(f"C: {first_class_meals}")
                if economy_meals:
                    meals_parts.append(f"Y: {economy_meals}")
                if crew_meals:
                    meals_parts.append(f"机组: {crew_meals}")
                meals_content = '    '.join(meals_parts)
                all_content_lines.append(f'<div class="content-line left-align">{meals_content}</div>')

            # 升舱价格表格 - 完整表格在一行显示
            upgrade_prices = segment.get('upgrade_prices', [])
            if upgrade_prices:
                # all_content_lines.append('<div class="table-line left-align">')
                all_content_lines.append('<table class="upgrade-table"><tr><th>舱位</th><th>价格</th></tr>')
                for price in upgrade_prices:
                    all_content_lines.append(f'<tr><td>{price.get("class", "")}</td><td>{price.get("price", "")}</td></tr>')
                all_content_lines.append('</table>')
                # all_content_lines.append('</div>')

            # 人数统计（标明C和Y）
            first_class_count = segment.get('first_class_count', '')
            economy_count = segment.get('economy_count', '')
            if first_class_count or economy_count:
                count_content = f"C: {first_class_count}    Y: {economy_count}"
                all_content_lines.append(f'<div class="content-line left-align">{count_content}</div>')

            # 头等舱布局 - 使用空格均匀分布
            if first_class_layout:
                # 第一行：1A 1C 1H 1K（用空格均匀分布）
                row1_content = "1A\t\t\t1C\t\t\t1H\t\t\t1K"
                all_content_lines.append(f'<div class="content-line first-class-row">{row1_content}</div>')

                # 第二行：2A 2C 2H 2K（用空格均匀分布）
                row2_content = "2A\t\t\t2C\t\t\t2H\t\t\t2K"
                all_content_lines.append(f'<div class="content-line first-class-row">{row2_content}</div>')

            # 先显示"经济舱:"标签单独一行
            economy_label = "经济舱:"
            all_content_lines.append(f'<div class="content-line left-align"><strong>{economy_label}</strong></div>')
            # 特殊乘客（经济舱换行后显示）
            special_passengers = segment.get('special_passengers', '')
            if special_passengers:
                special_passengers_list = special_passengers.split('\n')
                new_list = []
                for k in special_passengers_list:
                    new_list.extend(wrap_string_by_chinese_width(k))
                for comm in new_list:
                    all_content_lines.append(f'<div class="special-passengers left-align">{comm}</div>')

            # 添加分隔线（如果不是最后一个航段）
            if i < len(segments) - 1:
                all_content_lines.append('<div class="content-line divider"></div>')

    # 将内容分配到各个区块中（每个区块13行）
    lines_per_block = 13
    total_blocks = (len(all_content_lines) + lines_per_block - 1) // lines_per_block
    total_blocks += 3
    logger.info(f"共{len(all_content_lines)}行,分{total_blocks}区")
    end_index = 0
    for block_index in range(total_blocks):
        start_index = end_index
        end_index = min(start_index + lines_per_block, len(all_content_lines) - 1)
        if start_index == end_index:
            break
        if ('first-class-row' in all_content_lines[end_index]):
            logger.info('头等舱布局跳过至第二页')
            end_index -= 1
        if '<tr><td>' in all_content_lines[end_index - 1]:
            logger.info('升舱价格跳过至第二页')
            while 'upgrade-table' not in all_content_lines[end_index]:
                end_index -= 1
        logger.info(f"第{block_index}块 {start_index} - {end_index}")
        html_content += f'\n        <div class="content-block" id="block-{block_index}">'

        for i in range(start_index, end_index):
            html_content += f'\n            {all_content_lines[i]}'
        if end_index == len(all_content_lines) - 1:
            html_content += f'\n            {all_content_lines[-1]}'
        html_content += '\n        </div>'

    html_content += """
    </div>
    <script>
        // 初始化
        document.addEventListener('DOMContentLoaded', function() {
            console.log('页面加载完成，采用多区块水平布局');
            console.log('总区块数:', document.querySelectorAll('.content-block').length);
        });
    </script>
</body>
</html>"""

    # 保存HTML文件
    filename = f"flight_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html"
    filepath = f'static/{filename}'

    try:
        with open(filepath, 'w', encoding='utf-8') as f:
            f.write(html_content)
        logger.info(f"HTML文件已成功生成: {filename}")
    except Exception as e:
        logger.info(f"保存HTML文件时出错: {e}")
        return None

    return filename


@app.route('/')
def index():
    """主页面"""
    logger.info("访问主界面")
    return render_template('index.html')


@app.route('/api/data', methods=['GET'])
def get_data():
    """获取数据"""
    data = load_data()
    return jsonify(data)


@app.route('/api/save', methods=['POST'])
def save_flight_data():
    """保存航班数据"""
    data = load_data()
    form_data = request.json
    logger.info(f"收到保存请求，航段数量: {len(form_data.get('segments', []))}")
    # 更新当前数据
    data['current_data'].update({
        "date": form_data.get('date', ''),
        "week": form_data.get('week', ''),
        "route_name": form_data.get('route_name', ''),
        "flight_number": form_data.get('flight_number', ''),
        "plane_number": form_data.get('plane_number', ''),
        "captain_config": form_data.get('captain_config', ''),
        "segments": form_data.get('segments', [])
    })
    save_data(data)

    return jsonify({"status": "success"})


@app.route('/api/basic_data', methods=['POST'])
def update_basic_data():
    """更新基础数据"""
    data = load_data()
    basic_data = request.json

    data['basic_data'].update(basic_data)
    save_data(data)

    return jsonify({"status": "success"})


@app.route('/api/generate', methods=['POST'])
def generate_flight_html():
    """生成HTML"""
    try:
        data = load_data()
        logger.info(f"开始生成HTML，当前数据航段数量: {len(data['current_data'].get('segments', []))}")
        filename = generate_html(data['current_data'])

        if filename:
            return jsonify({
                "status": "success",
                "filename": filename,
                "url": f"/static/{filename}"
            })
        else:
            return jsonify({
                "status": "error",
                "message": "生成HTML文件失败"
            }), 500

    except Exception as e:
        logger.info(f"生成HTML时出错: {e}")
        print(format_exc())
        return jsonify({
            "status": "error",
            "message": f"生成HTML时出错: {str(e)}"
        }), 500


@app.route('/api/clear', methods=['POST'])
def clear_data():
    """清空数据"""
    data = load_data()
    data['current_data'] = {
        "date": "",
        "week": "",
        "route_name": "",
        "flight_number": "",
        "plane_number": "",
        "captain_config": "",
        "segments": [
            {
                "segment_number": "1",
                "departure_time": "",
                "arrival_time": "",
                "duration": "",
                "distance": "",
                "altitude": "",
                "airport": "",
                "first_class_meals": "",
                "economy_meals": "",
                "crew_meals": "",
                "upgrade_prices": [
                    {"class": "C", "price": "500"},
                    {"class": "Y", "price": "300"}
                ],
                "first_class_layout": False,
                "first_class_count": "",
                "economy_count": "",
                "special_passengers": ""
            }
        ]
    }
    save_data(data)
    return jsonify({"status": "success"})


@app.route('/static/<filename>')
def serve_html(filename):
    """提供静态HTML文件"""
    try:
        return send_file(f'static/{filename}')
    except Exception as e:
        return f"文件未找到: {e}", 404


if __name__ == '__main__':
    # 确保static目录存在
    if not os.path.exists('static'):
        os.makedirs('static')
    if not os.path.exists('templates'):
        os.makedirs('templates')

    logger.info("服务器启动在 http://localhost:5050")
    logger.info("请确保在templates目录中有index.html文件")
    app.run(debug=False, host='0.0.0.0', port=5000)
